﻿using HongYeSystemWebApi.Templet.Entity.ApiResult;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; 
using System;
using System.Linq;
using System.Reflection;
using Castle.DynamicProxy;
using Microsoft.AspNetCore.Builder;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;

namespace HongYeSystemWebApi.Templet.Core.Infrastructure
{
    public static class Bootstrapper
    { 
        /// <summary>
        /// 添加服务
        /// </summary>
        /// <param name="services"></param>
        public static void AddService(this IServiceCollection services)
        {
            services.AddSingleton(new ProxyGenerator());
            Type[] typesInterface = Assembly.Load("HongYeSystemWebApi.Templet.IService").GetTypes();
            Type[] typesImpl = Assembly.Load("HongYeSystemWebApi.Templet.Service").GetTypes();
            foreach (var item in typesInterface)
            {
                var impl = typesImpl.FirstOrDefault(w => item.Name.EndsWith(w.Name));
                if (impl != null)
                {
                    //services.AddScoped(item, impl);
                    AddProxiedScoped(services, item, impl);
                }
            }
        }
        private static void AddProxiedScoped(this IServiceCollection services, Type tInterface, Type tImpl)
        {
            services.AddScoped(tImpl);
            services.AddScoped(tInterface, serviceProvider =>
            {
                var proxyGenerator = serviceProvider.GetRequiredService<ProxyGenerator>();
                var actual = serviceProvider.GetRequiredService(tImpl);
                var interceptors = serviceProvider.GetServices<IInterceptor>().ToArray();
                return proxyGenerator.CreateInterfaceProxyWithTarget(tInterface, actual, interceptors);
            });
        }

        /// <summary>
        /// 静态文件
        /// </summary>
        /// <param name="app"></param>
        /// <param name="configuration"></param>
        public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, IConfiguration configuration)
        {
            string currentPath = System.IO.Directory.GetCurrentDirectory();
            var SecretKey = configuration["JwtConfig:SecretKey"];
            //设备图片路径设置
            string deviceSavePath = configuration["StaticFile:ExcelFile:FilePath"];
            deviceSavePath = $"{currentPath}/{deviceSavePath}";
            if (!Directory.Exists(deviceSavePath))
            {
                Directory.CreateDirectory(deviceSavePath);
            }
            string deviceRequestPath = configuration.GetSection("StaticFile:ExcelFile:RequestPath").Value;
            if (!string.IsNullOrEmpty(deviceSavePath) && !string.IsNullOrEmpty(deviceRequestPath))
            {
                app = app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(deviceSavePath),
                    RequestPath = deviceRequestPath
                });
            }
            return app;
        }





        /// <summary>
        /// 添加模型验证
        /// </summary>
        /// <param name="services"></param>
        public static void AddModelStateInvalid(this IServiceCollection services)
        {
            //模型绑定 特性验证，自定义返回格式
            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = actionContext =>
                {
                    //获取验证失败的模型字段 
                    var errors = actionContext.ModelState
                    .Where(e => e.Value.Errors.Count > 0)
                    .Select(e => e.Value.Errors.First().ErrorMessage)
                    .ToList();
                    var strErrorMsg = string.Join(",", errors);
                    if (strErrorMsg.Contains("Could not convert string") || strErrorMsg.Contains("Error converting value"))
                    {
                        strErrorMsg = "参数类型错误";
                    }
                    //设置返回内容
                    var result =   ApiResult.False( strErrorMsg, 400);
                    return new BadRequestObjectResult(result);
                };
            });
        }

  }
}